package com.project.smarthome.common.widget.circle;

import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import java.util.Random;

/**
 * 空气净化器绘制小颗粒view
 */
public class CircleView extends View {
    private static final String TAG = "CircleView";
    private Paint mDotPaint;//绘制颗粒
    private
    @ColorInt
    int mPaintColor;

    private ValueAnimator mOvalRotateAnimator;
    private ValueAnimator mOvalSizeAnimator;
    private ValueAnimator mDotMoveAnimator;
    private Random mRandom = new Random();

    private AnimatorSet mAnimatorSet;

    private Oval[] mOvals;
    private Dot[] mDots;
    private int mCenterX, mCenterY;
    private float mRotateAngle = 0.0f;

    private int mNumOfDot = 30;
    private int mNumOfOval = 30;
    private int mOvalRadius = 200;//圆圈的直径大小
    private int mOvalRegionWidth = mOvalRadius * 2 - 15;
    private int mOvalRegionHeight = mOvalRadius * 2;
    private int mOvalRotateDuration = 3000;
    private float mOvalStrokeWidth = 3.0f;
    private int mOvalSizeDuration = 2000;
    private int mOvalSizeExpendWidth = 50;
    private int mDotMovingDuration = 1000;
    private int mOvalAlphaDelta = 20;
    private int mOvalMinAlpha = 20;

    //颗粒移速
    private float mDotMaxVelocity;
    private float mDotMinVelocity;
    private float mDotMaxVelocityPercent = 0.16f;
    private float mDotMinVelocityPercent = 0.06f;

    //颗粒大小
    private float mDotMaxRadius;
    private float mDotMinRadius;
    private float mDotMaxRadiusPercent = 0.4f;
    private float mDotMinRadiusPercent = 0.1f;

    //当停止绘制不再增加小圆点时为false
    private boolean mIsDraw = false;

    private int mDotMinAlpha = 100;
    private int mDotMaxAplha = 255;
    private int mDotBornMargin = 30;

    public CircleView(Context context) {
        super(context);
        setup();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setup();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CircleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setup();
    }

    private void setup() {
        mPaintColor = Color.WHITE;
        mDotPaint = new Paint();
        mDotPaint.setColor(mPaintColor);
        mDotPaint.setAntiAlias(true);
        mDotPaint.setStyle(Paint.Style.FILL);

        /*mOvalPaint = new Paint();
        mOvalPaint.setColor(mPaintColor);
        mOvalPaint.setAntiAlias(true);
        mOvalPaint.setStrokeWidth(mOvalStrokeWidth);
        mOvalPaint.setStyle(Paint.Style.STROKE);*/

        mOvalRotateAnimator = new ValueAnimator();
        mOvalRotateAnimator.setInterpolator(new LinearInterpolator());
        mOvalRotateAnimator.setDuration(mOvalRotateDuration);
        mOvalRotateAnimator.setFloatValues(0, 360);
        mOvalRotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mRotateAngle = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        mOvalRotateAnimator.setRepeatMode(ValueAnimator.RESTART);
        mOvalRotateAnimator.setRepeatCount(ValueAnimator.INFINITE);

        mOvalSizeAnimator = new ValueAnimator();
        mOvalSizeAnimator.setInterpolator(new LinearInterpolator());
        mOvalSizeAnimator.setDuration(mOvalSizeDuration);
        mOvalSizeAnimator.setIntValues(0, mOvalSizeExpendWidth);
        mOvalSizeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                for (int i = 0; i < mNumOfOval; i++) {
                    Oval oval = mOvals[i];
                    oval.mRectF.set(
                            oval.mOriginalRectF.left + value,
                            oval.mOriginalRectF.top,
                            oval.mOriginalRectF.right - value,
                            oval.mOriginalRectF.bottom);
                }
                invalidate();
            }
        });
        mOvalSizeAnimator.setRepeatMode(ValueAnimator.REVERSE);
        mOvalSizeAnimator.setRepeatCount(ValueAnimator.INFINITE);

        mDotMoveAnimator = new ValueAnimator();
        mDotMoveAnimator.setInterpolator(new LinearInterpolator());
        mDotMoveAnimator.setDuration(mDotMovingDuration);
        mDotMoveAnimator.setIntValues(0, mDotMovingDuration);
        mDotMoveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                for (int i = 0; i < mNumOfDot; i++) {
                    Dot dot = mDots[i];
                    dot.mDistance -= dot.mVelocity;
                    dot.mAlpha = (int) (dot.mBaseAlpha * ((double) (dot.mDistance - mOvalRadius) / (dot.mBaseDistance - mOvalRadius)));
                    if (dot.mDistance < mOvalRadius) {
                        randomDot(dot);
                    }
                }
                invalidate();
            }
        });
        mDotMoveAnimator.setRepeatMode(ValueAnimator.RESTART);
        mDotMoveAnimator.setRepeatCount(ValueAnimator.INFINITE);

        mAnimatorSet = new AnimatorSet();
        mAnimatorSet.playTogether(mDotMoveAnimator);
        //mAnimatorSet.playTogether(mOvalRotateAnimator, mOvalSizeAnimator, mDotMoveAnimator);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSize(widthMeasureSpec);
        int height = MeasureSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
        updateValue(height);
        mCenterX = width / 2;
        mCenterY = (int) (height / 3.2);
    }

    private int MeasureSize(int measureSpec) {
        return MeasureSpec.getSize(measureSpec);
    }

    /**
     * height 屏幕的高度，单位：px
     * <p>
     * 1.根据不同手机屏幕的高度比例得到小圆点的半径
     * <p>
     * 2.根据不同手机屏幕的高度比例得到小圆点的移速
     */
    private void updateValue(int mheight) {
        int height = mheight / 50;
        mDotMaxVelocity = height * mDotMaxVelocityPercent;
        mDotMinVelocity = height * mDotMinVelocityPercent;
        mDotMaxRadius = height * mDotMaxRadiusPercent;
        mDotMinRadius = height * mDotMinRadiusPercent;

    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
       /* mCenterX = w / 2;
        mCenterY = h / 2;*/
        setupDrawables(w, h);
        if (mAnimatorSet.isStarted()) {
            mAnimatorSet.cancel();
        }
        mAnimatorSet.start();
    }

    private void setupDrawables(int w, int h) {
        mOvals = new Oval[mNumOfOval];
        int alpha = 255;
        for (int i = 0; i < mNumOfOval; i++) {
            RectF rectF = new RectF(
                    mCenterX - mOvalRegionWidth / 2,
                    mCenterY - mOvalRegionHeight / 2,
                    mCenterX + mOvalRegionWidth / 2,
                    mCenterY + mOvalRegionHeight / 2);
            alpha = alpha - mOvalAlphaDelta;
            if (alpha < mOvalMinAlpha)
                alpha = mOvalMinAlpha;
            mOvals[i] = new Oval(rectF, 0, alpha);
        }

        mDots = new Dot[mNumOfDot];
        for (int i = 0; i < mNumOfDot; i++) {
            mDots[i] = new Dot(mCenterX, mCenterY);
            randomDot(mDots[i]);
        }
    }

    private void randomDot(Dot dot) {
        int w = getWidth();
        int h = getHeight();
        float radius = 0;
        int minDistance = mOvalRadius + mDotBornMargin;
        int alpha = mRandom.nextInt(mDotMaxAplha - mDotMinAlpha) + mDotMinAlpha;
        double angle = Math.toRadians(mRandom.nextInt(360));
        int distance = mRandom.nextInt((int) Math.sqrt(w / 2.0 * w / 2.0 + h / 2.0 * h / 2.0) - minDistance) + minDistance;
        float velocity = mRandom.nextInt((int) (mDotMaxVelocity - mDotMinVelocity)) + mDotMinVelocity;
        if (mIsDraw) {
            radius = mRandom.nextInt((int) (mDotMaxRadius - mDotMinRadius)) + mDotMinRadius;
        } else {//当radius为0是，就相当于没有小点增加
            radius = 0;
        }
        dot.setAlpha(alpha);
        dot.setBaseAlpha(alpha);
        dot.setAngle(angle);
        dot.setDistance(distance);
        dot.setBaseDistance(distance);
        dot.setVelocity(velocity);
        dot.setRadius(radius);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (int i = 0; i < mNumOfDot; i++) {
            Dot dot = mDots[i];
            mDotPaint.setAlpha(dot.mAlpha);
            canvas.drawCircle(dot.getCenterX(), dot.getCenterY(), dot.mRadius, mDotPaint);
        }

        //canvas.rotate(mRotateAngle, mCenterX, mCenterY);
        /*for (int i = mNumOfOval - 1; i >= 0; i--) {
            Oval oval = mOvals[i];
            mOvalPaint.setAlpha(oval.mAlpha);
            canvas.rotate(360/mNumOfOval, mCenterX, mCenterY);
            canvas.drawOval(oval.mRectF, mOvalPaint);
        }*/
    }

    public void setPaintColor(@ColorInt int color) {
        mPaintColor = color;
        mDotPaint.setColor(mPaintColor);
        //mOvalPaint.setColor(mPaintColor);
    }

    //开关小颗粒
    public void stopDraw(boolean bool) {
        this.mIsDraw = bool;
    }

    //颗粒大小
    public void setPaintSize(float mDotMaxRadiusPercent, float mDotMinRadiusPercent) {
        this.mDotMaxRadiusPercent = mDotMaxRadiusPercent;
        this.mDotMinRadiusPercent = mDotMinRadiusPercent;
    }

    //往中间汇聚的范围直径大小
    public void setOvalRadius(int mOvalRadius) {
        this.mOvalRadius = mOvalRadius;
    }

    public int getPaintColor() {
        return mPaintColor;
    }

    //设置粒子数量
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setNumOfDot(final int numOfDot) {
        postOnAnimation(new Runnable() {
            @Override
            public void run() {
                Dot[] copyDots = new Dot[numOfDot];
                System.arraycopy(mDots, 0, copyDots, 0, Math.min(mDots.length, numOfDot));

                int numberDelta = numOfDot - mNumOfDot;
                if (numberDelta > 0) {
                    for (int i = 0; i < numberDelta; i++) {
                        copyDots[i + mNumOfDot] = new Dot(mCenterX, mCenterY);
                        randomDot(copyDots[i + mNumOfDot]);
                    }
                }
                mNumOfDot = numOfDot;
                mDots = copyDots;
            }
        });
        postInvalidateOnAnimation();
    }

    //设置粒子运行速度
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void setDotVelocity(final float mDotMaxVelocityPercent, final float mDotMinVelocityPercent) {

        this.mDotMaxVelocityPercent = mDotMaxVelocityPercent;
        this.mDotMinVelocityPercent = mDotMinVelocityPercent;

        postOnAnimation(new Runnable() {


            @Override
            public void run() {


                if (mDotMinVelocity <= 0) {
                    mDotMinVelocity = 1;
                }
                mDotMaxVelocity = Math.max(mDotMaxVelocity, mDotMinVelocity);
            }
        });
        postInvalidateOnAnimation();
    }

    /*//圆圈转速
    public void setOvalRotateDuration(final int ovalRotateDuration) {
        postOnAnimation(new Runnable() {

            @Override
            public void run() {
                mOvalRotateDuration = ovalRotateDuration;
                mOvalRotateDuration = Math.max(mOvalRotateDuration, 200);
                mOvalRotateAnimator.setDuration(mOvalRotateDuration);
            }
        });
        postInvalidateOnAnimation();
    }*/

   /* //圆圈缩放大小
    public void setOvalSizeExpendWidth(final int ovalSizeExpendWidth) {
        postOnAnimation(new Runnable() {

            @Override
            public void run() {
                mOvalSizeExpendWidth = ovalSizeExpendWidth;
                mOvalSizeExpendWidth = Math.max(mOvalSizeExpendWidth, 0);
                mOvalSizeAnimator.setIntValues(0, mOvalSizeExpendWidth);
            }
        });
        postInvalidateOnAnimation();
    }*/
}
